package com.wlf.admin.system.service;

import cloud.tianai.captcha.application.ImageCaptchaApplication;
import cloud.tianai.captcha.spring.plugins.secondary.SecondaryVerificationApplication;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.MD5;
import com.wlf.admin.common.config.SysConfig;
import com.wlf.admin.common.dto.CacheKey;
import com.wlf.admin.common.dto.Const;
import com.wlf.admin.common.dto.LayuiMiniDto;
import com.wlf.admin.common.util.AjaxBean;
import com.wlf.admin.common.util.AjaxError;
import com.wlf.admin.system.domain.SysMenu;
import com.wlf.admin.system.domain.SysUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j

@Service
public class IndexService {
    @Resource
    private SysMenuService menuService;
    @Resource
    private SysUserService userService;
    @Resource
    private SysConfig sysConfig;
    @Resource
    private ImageCaptchaApplication imageCaptchaApplication;

    /**
     * 功能描述: 前端框架初始化需要的数据
     *
     * @author wlf 2023/9/13 10:28
     */
    public LayuiMiniDto init() {
        List<SysMenu> menuList = menuService.getMenuListByUserId(StpUtil.getLoginIdAsLong());
        return LayuiMiniDto.handleMenu(menuList);
    }

    /**
     * 功能描述: 登录请求
     *
     * @author wlf 2023/9/13 10:27
     */
    public AjaxBean login(String uname, String passwd, boolean remember, String cid) {
        if (sysConfig.getOpenCaptcha()) {
            if(StrUtil.isBlank(cid)){
                return AjaxBean.get(401, "参数不全, 登陆失败");
            }
            // 如果开启了二次验证
            if (imageCaptchaApplication instanceof SecondaryVerificationApplication) {
                boolean verification = ((SecondaryVerificationApplication) imageCaptchaApplication)
                        .secondaryVerification(cid);
                if (!verification) {
                    return AjaxBean.getError("请校验验证码!");
                }
            }
        }
        if (StrUtil.hasBlank(uname, passwd)) {
            return AjaxBean.get(401, "参数不全, 登陆失败");
        }
        // 判断用户是否存在
        SysUser sysUser = userService.lambdaQuery().eq(SysUser::getLoginNo, uname).one();
        if (sysUser == null) {
            return AjaxBean.getError("用户名或密码不正确,登陆失败");
        }
        String s = MD5.create().digestHex16(passwd);
        if (!s.equals(sysUser.getPssswd())) {
            return AjaxBean.getError("用户名或密码不正确,登陆失败");
        }
        if (Const.UserStatus.invalid.name().equals(sysUser.getStatus())) {
            return AjaxBean.getError("用户已失效,登陆失败");
        }
        SaLoginModel loginModel = new SaLoginModel();
        loginModel.setDevice(Const.LoginDevice.PC.name());
        loginModel.setIsLastingCookie(remember);
        StpUtil.login(sysUser.getId(), loginModel);
        return AjaxBean.getOkMsg("登陆成功");
    }

    /**
     * 功能描述: 修改密码
     *
     * @author wlf 2023/9/13 10:36
     */
    public AjaxBean userPass(String pass1, String pass2, String pass3) {
        SysUser sysUser = userService.getLoginUser();
        if (!Const.md5.digestHex16(pass1).equals(sysUser.getPssswd())) {
            AjaxError.getAndThrow("原始密码输入错误，修改失败");
        }
        if (!pass2.equals(pass3)) {
            AjaxError.getAndThrow("两次密码输入不一致，请重新输入");
        }
        boolean update = userService.lambdaUpdate()
                .set(SysUser::getPssswd, Const.md5.digestHex16(pass2))
                .eq(SysUser::getId, sysUser.getId()).update();
        if (update) {
            // 修改密码过后退出登录
            StpUtil.logout(sysUser.getId(), Const.LoginDevice.PC.name());
        }
        return AjaxBean.getByBool(update, "密码修改成功", "密码修改失败");
    }


    /**
     * 功能描述: 清理缓存方法
     *
     * @author wlf 2023/9/13 14:07
     */
    @Caching(
            evict = {
                    @CacheEvict(cacheNames = CacheKey.role, allEntries = true),
                    @CacheEvict(cacheNames = CacheKey.menu, allEntries = true),
                    @CacheEvict(cacheNames = CacheKey.user, allEntries = true),
                    @CacheEvict(cacheNames = CacheKey.organ, allEntries = true),
                    @CacheEvict(cacheNames = CacheKey.power, allEntries = true),
            }
    )
    public void cleanCache() {

    }
}
